#!/bin/bash
#==============================================================#
# File    :  Oracle_down.sh
# Ctime   :  2024/10/28
# Mtime   :  2025/09/09
# Version :  1.7
# author  :  楚枫默寒
#==============================================================#

if [[ $EUID -ne 0 ]]; then
    echo "此脚本必须以root权限运行!"
    exit 1
fi

#字体颜色
function color_setting(){
    RC='\033[31;1m'        #红色 error
    GC='\033[32;1m'        #绿色 success
    YC='\033[33;1m'        #黄色 warning
    BC='\033[34;1m'        #蓝色 output
    DC='\033[35;1m'        #粉色 detail
    AC='\033[36;1m'        #天蓝 info
    EC='\033[0m'           #黑白 EC
}

function file_conf(){
#下载地址
httpaddr="http://xxx.xxx.xxx.xxx/oracle/Allsetup"  #此处为所有Oracle安装文件地址（自备）
      
#文件信息
file_setup='OracleShellInstall'

file_11_sin="p13390677_112040_Linux-x86-64_1of7.zip p13390677_112040_Linux-x86-64_2of7.zip"
file_11_rac="p13390677_112040_Linux-x86-64_1of7.zip p13390677_112040_Linux-x86-64_2of7.zip p13390677_112040_Linux-x86-64_3of7.zip"
file_11_opa="p6880880_112000_Linux-x86-64.zip"
file_11_rlw="rlwrap-0.42.tar.gz"

file_12_sin="LINUX.X64_122010_db_home.zip"
file_12_rac="LINUX.X64_122010_db_home.zip LINUX.X64_122010_grid_home.zip"
file_12_opa="p6880880_122010_Linux-x86-64.zip"
file_12_rlw="rlwrap-0.44.tar.gz"

file_19_sin="LINUX.X64_193000_db_home.zip"
file_19_rac="LINUX.X64_193000_db_home.zip LINUX.X64_193000_grid_home.zip"
file_19_opa="p6880880_190000_Linux-x86-64.zip"
file_19_rlw="rlwrap-0.44.tar.gz"

file_21_sin="LINUX.X64_213000_db_home.zip"
file_21_rac="LINUX.X64_213000_db_home.zip LINUX.X64_213000_grid_home.zip"
file_21_opa="p6880880_210000_Linux-x86-64.zip"
file_21_rlw="rlwrap-0.44.tar.gz"

#==============================================================#
#                             补丁信息                         #
#==============================================================#
# -gpa   Grid PSU/RU 补丁编号
# -opa   Oracle PSU/RU 补丁编号
# -jpa   Oracle OJVM PSU/RU 补丁编号

opa_11_sin="p35574075_112040_Linux-x86-64.zip"
gpa_11_rac="p35685688_112040_Linux-x86-64.zip p18370031_112040_Linux-x86-64.zip"
jpa_11_gen="p35685663_112040_Linux-x86-64.zip"

opa_12_sin="p35966787_122010_Linux-x86-64.zip"
gpa_12_rac="p35745595_122010_Linux-x86-64.zip"
jpa_12_gen="p35926712_122010_Linux-x86-64.zip"

opa_19_sin="p37960098_190000_Linux-x86-64.zip"
gpa_19_rac="p37957391_190000_Linux-x86-64.zip"
jpa_19_gen="p37847857_190000_Linux-x86-64.zip"

opa_21_sin="p37655430_210000_Linux-x86-64.zip"
gpa_21_rac="p37642955_210000_Linux-x86-64.zip"
jpa_21_gen=""
}

#IP4判断
regex="\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\b"

is_valid_ip() {
    [[ $1 =~ $regex ]]
}

#==============================================================#
#                         获取操作系统信息                     #
#==============================================================#
function get_os_info() {
  local os_file
  os_file=$(if [[ -f "/etc/system-release" ]]; then echo /etc/system-release; else echo /etc/redhat-release; fi)
  os_version=$(cat ${os_file}|grep -E -o '[0-9]{1,3}'|head -n 1)
}

#==============================================================#
#                    选择数据库安装模式和版本                  #
#==============================================================#
function select_db_options() {
  local dbversion
  while :; do
    #安装模式
    echo
    read -rep "$(echo -e "${AC}请选择安装模式 [单机(si)/单机ASM(sa)/集群(rac)] : ${EC}")" oracle_install_mode
    case "$oracle_install_mode" in
    si) oracle_install_mode=single ;;
    sa) oracle_install_mode=standalone ;;
    esac
    if [[ "$oracle_install_mode" =~ ^(single|standalone|rac)$ ]]; then
      echo -e ${GC}"数据库安装模式: $oracle_install_mode "${EC}
      break
    else
      echo -e ${RC}"数据库安装模式输入错误，请重新选择！"${EC}
    fi
  done
  #数据库版本
  case ${os_version} in
    6)
      dbversion='11|12';;
    *)
      dbversion='11|12|19|21';;
  esac
  while :; do
    echo
    read -rep "$(echo -e "${AC}请选择数据库版本 [$dbversion] : ${EC}")" db_version
    if [[ "$db_version" =~ ^($dbversion)$ ]]; then
      echo -e ${GC}"数据库版本: $db_version "${EC}
      break
    else
      echo -e ${RC}"数据库版本输入错误，请重新选择！"${EC}
    fi
  done
  while :; do
    echo
    read -rep "$(echo -e "${AC}是否仅安装软件 [Y/N] : ${EC}")" -i "N" only_soft
  done
  echo
  read -rep "$(echo -e "${AC}是否开始下载安装文件(Y/N) : ${EC}")" -i "N" downfile
  echo
  #配置下载清单
  case "${db_version}" in
      11) 
          local opa=$(echo ${opa_11_sin}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local gpa=$(echo ${gpa_11_rac}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local jpa=$(echo ${jpa_11_gen}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          if [[ ${oracle_install_mode} == "single" ]];then
            file_downoad "${file_setup} ${file_11_sin} ${file_11_opa} ${file_11_rlw} ${opa_11_sin} ${jpa_11_gen}"
          else
            file_downoad "${file_setup} ${file_11_rac} ${file_11_opa} ${file_11_rlw} ${gpa_11_rac} ${jpa_11_gen}"
          fi
          setup_command ${oracle_install_mode} ${opa} ${gpa} ${jpa} 
      ;;
      12)
          local opa=$(echo ${opa_12_sin}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local gpa=$(echo ${gpa_12_rac}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local jpa=$(echo ${jpa_12_gen}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          if [[ ${oracle_install_mode} == "single" ]];then
              file_downoad "${file_setup} ${file_12_sin} ${file_12_opa} ${file_12_rlw} ${opa_12_sin} ${jpa_12_gen}"
          else
              file_downoad "${file_setup} ${file_12_rac} ${file_12_opa} ${file_12_rlw} ${gpa_12_rac} ${jpa_12_gen}"
          fi
          setup_command ${oracle_install_mode} ${opa} ${gpa} ${jpa} 
      ;;
      19)
          local opa=$(echo ${opa_19_sin}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local gpa=$(echo ${gpa_19_rac}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local jpa=$(echo ${jpa_19_gen}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          if [[ ${oracle_install_mode} == "single" ]];then
            file_downoad "${file_setup} ${file_19_sin} ${file_19_opa} ${file_19_rlw} ${opa_19_sin} ${jpa_19_gen}"
          else
            file_downoad "${file_setup} ${file_19_rac} ${file_19_opa} ${file_19_rlw} ${gpa_19_rac} ${jpa_19_gen}"
          fi
          setup_command ${oracle_install_mode} ${opa} ${gpa} ${jpa} 
      ;;
      21)
          local opa=$(echo ${opa_21_sin}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local gpa=$(echo ${gpa_21_rac}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          local jpa=$(echo ${jpa_21_gen}|awk -F '[_]' '{print $1}'|tr -d 'a-zA-Z')
          if [[ ${oracle_install_mode} == "single" ]];then
            file_downoad "${file_setup} ${file_21_sin} ${file_21_opa} ${file_21_rlw} ${opa_21_sin} ${jpa_21_gen}"
          else
            file_downoad "${file_setup} ${file_21_rac} ${file_21_opa} ${file_21_rlw} ${gpa_21_rac} ${jpa_21_gen}"
          fi
          setup_command ${oracle_install_mode} ${opa} ${gpa} 
      ;;
  esac
}

#==============================================================#
#                          下载安装包                          #
#==============================================================#
function file_downoad() {
  local filelist=$1
  if [[ ${downfile^^} = "Y" ]];then
    for d_file in ${filelist};do
      wget -O /soft/${d_file} ${httpaddr}/${d_file}
    done
    echo -e ${YC}"安装文件已下载完成！"${EC}
  fi
}

#==============================================================#
#                       配置安装参数过程                       #
#==============================================================#
#据库名称
pro_dataname(){
  echo
  read -rep "$(echo -e "${AC}请输入数据库名称 : ${EC}")" -i "orcl" dataname
}
#软件安装目录
pro_basepath(){
  echo
  read -rep "$(echo -e "${AC}请输入软件安装目录 : ${EC}")" -i "/app" basepath
}
#密码
pwd_root(){
  echo
  read -rep "$(echo -e "${AC}请输入主机root密码 : ${EC}")" -i "oracle" root_pwd
}
pwd_orac(){
  echo
  read -rep "$(echo -e "${AC}请输入主机oracle密码 : ${EC}")" -i "oracle" orac_pwd
}
pwd_grid(){
  echo
  read -rep "$(echo -e "${AC}请输入主机grid密码 : ${EC}")" -i "oracle" grid_pwd
}
pwd_dp(){
  echo
  read -rep "$(echo -e "${AC}请输入数据库SYS密码 : ${EC}")" -i "oracle" dp_pwd
}
#字符集
pro_character(){
  echo
  read -rep "$(echo -e "${AC}请指定database character [AL32UTF8/ZHS16GBK] : ${EC}")" -i "AL32UTF8" char_d
  echo
  read -rep "$(echo -e "${AC}请指定national character : ${EC}")" -i "AL16UTF16" char_n
}
#redo大小
pro_redosize(){
  echo
  read -rep "$(echo -e "${AC}请输入redo大小M [100] : ${EC}")" -i "300" redo_s
}
#数据文件目录
pro_datapath(){
  echo
  read -rep "$(echo -e "${AC}请输入数据文件目录 : ${EC}")" -i "/db" datapath
}
#公网IP
pro_pips(){
  echo
  while true; do
    read -rep "$(echo -e "${AC}请输入公网IP(逗号分隔) : ${EC}")" pips
    if [[ -n ${pips} ]];then
      valid=true
      for ip_p in $(echo ${pips}| tr ',' ' '); do
        if ! is_valid_ip "${ip_p}"; then
          echo -e ${RC}"错误：'$ip_p' 不是一个合法的IPv4地址，请重新输入所有IP。"${EC}
          valid=false
          break
        fi
      done
      if [ "$valid" = true ]; then
          echo -e ${GC}"公网IP：" "${pips[@]}"${EC}
          break
      fi
    fi
  done
}
#虚拟IP
pro_vips(){
  echo
  while true; do
    read -rep "$(echo -e "${AC}请输入虚拟IP(逗号分隔) : ${EC}")" vips
    if [[ -n ${vips} ]];then
      valid=true
      for ip_v in $(echo ${vips}| tr ',' ' '); do
        if ! is_valid_ip "${ip_v}"; then
          echo -e ${RC}"错误：'$ip_v' 不是一个合法的IPv4地址，请重新输入所有IP。"${EC}
          valid=false
          break
        fi
      done
      if [ "$valid" = true ]; then
          echo -e ${GC}"虚拟IP：" "${vips[@]}"${EC}
          break
      fi
    fi
  done
}
#scan IP
pro_sips(){
  echo
  while true; do
    read -rep "$(echo -e "${AC}请输入scan IP : ${EC}")" sips
    if [[ -n ${sips} ]];then
      valid=true
      for ip_s in $(echo ${sips}| tr ',' ' '); do
        if ! is_valid_ip "${ip_s}"; then
          echo -e ${RC}"错误：'$ip_s' 不是一个合法的IPv4地址，请重新输入所有IP。"${EC}
          valid=false
          break
        fi
      done
      if [ "$valid" = true ]; then
          echo -e ${GC}"scan IP：" "${sips[@]}"${EC}
          break
      fi
    fi
  done
}
#Ocr asm Disk
pro_asm_orc(){
  echo
  read -rep "$(echo -e "${AC}请输入Ocr asm Disk : ${EC}")" -i "/dev/sdb" OAD
}
#Data asm Disk
pro_asm_data(){
      echo
      case "$oracle_install_mode" in
        standalone)
          read -rep "$(echo -e "${AC}请输入Data asm Disk : ${EC}")" -i "/dev/sdb" DAD;;
        *)
          read -rep "$(echo -e "${AC}请输入Data asm Disk : ${EC}")" -i "/dev/sdc" DAD;;
      esac
}
#eth0
pro_lf(){
      echo
      read -rep "$(echo -e "${AC}请输入local ip ifname : ${EC}")" -i "eth0" eth_local
}
#eth1
pro_pf(){
      echo
      read -rep "$(echo -e "${AC}请输入rac private ip ifname : ${EC}")" -i "eth1" eth_rac
}

#==============================================================#
#                         配置安装命令                         #
#==============================================================#
function setup_command() {
  echo 
  echo -e  ${RC}"请按提示输入相关安装参数!"${EC}
  local install_mode=$1
  local opa=$2
  local gpa=$3
  local jpa=$4
  local prename=$(echo $HOSTNAME | sed 's/[0-9]*$//')
  case "$oracle_install_mode" in
     single)
        pro_lf
        pro_basepath
        pro_datapath
        pro_dataname
        pwd_orac
        pwd_dp
        pro_character
        pro_redosize
        options=(
                "./OracleShellInstall -n ${HOSTNAME} \`# hostname\` \\"
                "-lf ${eth_local} \`# local ip ifname\` \\"
                "-op '${orac_pwd}' \`# oracle password\` \\"
                "-dp '${dp_pwd}' \`# sys/system password\` \\"
                "-d ${basepath} \`# software base dir\` \\"
                "-ord ${datapath} \`# data dir\` \\"
                "-ard ${datapath}/archivelog \`# archive dir\` \\"
                "-o ${dataname} \`# dbname\` \\"
                "-ds ${char_d} \`# database character\` \\"
                "-ns ${char_n} \`# national character\` \\"
                "-redo ${redo_s} \`# redo size\` \\"
                "-opa ${opa} \`# oracle PSU/RU\` \\"
                "-jpa ${jpa} \`# OJVM PSU/RU\` \\"
                "-lrp N \`# local yum db\` \\"
                "-opd Y \`# optimize db\`")
        case "${db_version}" in
            21)
              unset options[12];;
        esac
        ;;
     standalone)
        pro_lf
        pwd_grid
        pwd_orac
        pwd_dp
        pro_asm_data
        pro_dataname
        pro_character
        pro_redosize
        options=(
                "./OracleShellInstall -n ${HOSTNAME} \`# hostname prefix\` \\"
                "-lf ${eth_local} \`# local ip ifname\` \\"
                "-gp '${grid_pwd}' \`# grid password\` \\"
                "-op '${orac_pwd}' \`# oracle password\` \\"
                "-dp '${dp_pwd}' \`# sys/system password\` \\"
                "-dd ${DAD} \`# rac data asm disk\` \\"
                "-o ${dataname} \`# dbname\` \\"
                "-ds ${char_d} \`# database character\` \\"
                "-ns ${char_n} \`# national character\` \\"
                "-redo ${redo_s} \`# redo size\` \\"
                "-gpa ${gpa} \`# oracle PSU/RU\` \\"
                "-jpa ${jpa} \`# OJVM PSU/RU\` \\"
                "-lrp N \`# local yum db\` \\"
                "-opd Y \`# optimize db\`")
        case "${db_version}" in
            21)
              unset options[11];;
        esac
        ;;
     rac)
        pwd_root
        pwd_grid
        pwd_orac
        pwd_dp
        pro_lf
        pro_pf
        pro_pips
        pro_vips
        pro_sips
        pro_asm_orc
        pro_asm_data
        pro_dataname
        pro_character
        pro_redosize
        options=(
                "./OracleShellInstall -n ${prename} \`# hostname prefix\` \\"
                "-hn ${prename}01,${prename}02 \`# rac node hostname\` \\"
                "-cn ${prename}-scan \`# cluster_name\` \\"
                "-rp '${root_pwd}' \`# root password\` \\"
                "-gp '${grid_pwd}' \`# grid password\` \\"
                "-op '${orac_pwd}' \`# oracle password\` \\"
                "-dp '${dp_pwd}' \`# sys/system password\` \\"
                "-lf ${eth_local} \`# local ip ifname\` \\"
                "-pf ${eth_rac} \`# rac private ip ifname\` \\"
                "-ri ${pips} \`# rac node public ip\` \\"
                "-vi ${vips} \`# rac virtual ip\` \\"
                "-si ${sips} \`# rac scan ip\` \\"
                "-od ${OAD} \`# rac ocr asm disk\` \\"
                "-dd ${DAD} \`# rac data asm disk\` \\"
                "-o ${dataname} \`# dbname\` \\"
                "-ds ${char_d} \`# database character\` \\"
                "-ns ${char_n} \`# national character\` \\"
                "-redo ${redo_s} \`# redo size\` \\"
                "-gpa ${gpa} \`# grid PSU/RU\` \\"
                "-jpa ${jpa} \`# OJVM PSU/RU\` \\"
                "-lrp N \`# local yum db\` \\"
                "-opd Y \`# optimize db\`")
        case "${db_version}" in
            21)
              unset options[19];;
        esac
        ;;
  esac
  if [[ ! ${only_soft} == "N" ]];then
    let ois=${#options[@]}-1
    options[$ois]="-ud Y `# only soft`"
  fi
}

#==============================================================#
#                            主程序                            #
#==============================================================#
function main() {
  color_setting
  file_conf
  get_os_info
  select_db_options
  if [[ -e /soft/OracleShellInstall ]];then  chmod +x /soft/OracleShellInstall; fi
  echo
  echo -e ${GC}"请按如下格式执行命令安装！"${EC}
  echo -e ${RC}"使用 'sh OracleShellInstall --help' 以获取更多帮助信息！\n"${EC}
  echo -e ${GC}
  for outcmd in "${options[@]}"; do
    echo "${outcmd%% *}" "${outcmd#* }"
  done
  echo -e ${EC}
}

main "$@"

